#include "mcsettings.h"
#include "cpphelper.h"
#include "mcsinglevalue.h"
#include "mcvecvalue.h"
#include "mcsettingsvalue.h"

namespace MCCommon
{

MCSettings::MCSettings()
{
}

MCSettings::~MCSettings()
{
   Clear();
}

MCSettings::MCSettings
(
    const MCSettings& other
)
{
    fNameIndexMap = other.fNameIndexMap;
    for( int i=0; i<(int)other.fSettingValues.size(); i++ )
    {
        fSettingValues.push_back( 
            other.fSettingValues[i]->Clone() );
    }
}

MCSettings&
MCSettings::operator = 
(
    const MCSettings& other 
)
{
    Clear();

    fNameIndexMap = other.fNameIndexMap;
    for( int i=0; i<(int)other.fSettingValues.size(); i++ )
    {
        fSettingValues.push_back( 
            other.fSettingValues[i]->Clone() );
    }

    return *this;
}

MCSettings*
MCSettings::Clone() const 
{
    return new MCSettings( *this );       
}

void 
MCSettings::Clear()
{
    fNameIndexMap.clear();
    CppHelper::SafeDel( fSettingValues );
}

bool 
MCSettings::IsHavingSetting
(
    const std::string& name
) const
{
    std::map< std::string, int>::const_iterator it = 
        fNameIndexMap.find( name );
    
    return ( it != fNameIndexMap.end() );
}

bool 
MCSettings::AddSetting
( 
    const std::string& name, 
    bool value
)
{
    bool isOK = false;
    
    if ( !IsHavingSetting( name ) )
    {
        IMCSettingValue* pValue = new MCSingleValue( value );
        isOK = AddSetting( name, pValue );
    }
    
    return isOK;
}

bool 
MCSettings::AddSetting
( 
    const std::string& name, 
    int value
)
{
    bool isOK = false;

    if ( !IsHavingSetting( name ) )
    {
        IMCSettingValue* pValue = new MCSingleValue( value );
        isOK = AddSetting( name, pValue );
    }

    return isOK;
}

bool 
MCSettings::AddSetting
( 
    const std::string& name, 
    double value
)
{
    bool isOK = false;

    if ( !IsHavingSetting( name ) )
    {
        IMCSettingValue* pValue = new MCSingleValue( value );
        isOK = AddSetting( name, pValue );
    }

    return isOK;
}

bool 
MCSettings::AddSetting
( 
    const std::string& name, 
    const std::string& value
)
{
    bool isOK = false;

    if ( !IsHavingSetting( name ) )
    {
        IMCSettingValue* pValue = new MCSingleValue( value );
        isOK = AddSetting( name, pValue );
    }

    return isOK;
} 

bool 
MCSettings::AddSetting
( 
    const std::string& name, 
    const char* value
)
{
    bool isOK = false;

    if ( !IsHavingSetting( name ) )
    {
        IMCSettingValue* pValue = new MCSingleValue( std::string( value ) );
        isOK = AddSetting( name, pValue );
    }

    return isOK;
}

bool 
MCSettings::AddSetting
( 
    const std::string& name, 
    const MCSettings& value  
)
{
    bool isOK = false;

    if ( !IsHavingSetting( name ) )
    {
        IMCSettingValue* pValue = new MCSettingListValue( value );
        isOK = AddSetting( name, pValue );
    }

    return isOK;
}

bool 
MCSettings::AddSetting
( 
    const std::string& name, 
    IMCSettingValue* value  
)
{
    bool isOK( 0 != value);
    
    if ( isOK )
    {
        fNameIndexMap.insert( std::make_pair(
            name, (int)fSettingValues.size() ) );
        fSettingValues.push_back( value );        
    }

    return isOK;    
}

bool 
MCSettings::GetSetting
( 
    const std::string& name, 
    bool& value
) const
{
    bool isOK( false);

    std::map< std::string, int >::const_iterator it = 
        fNameIndexMap.find( name );
    if ( it != fNameIndexMap.end() )
    {
        isOK = true;
        value = fSettingValues[ it->second ]->GetBool(); 
    }
    
    return isOK;
}

bool 
MCSettings::GetSetting
( 
    const std::string& name, 
    int& value
) const
{
    bool isOK( false);

    std::map< std::string, int >::const_iterator it = 
        fNameIndexMap.find( name );
    if ( it != fNameIndexMap.end() )
    {
        isOK = true;
        value = fSettingValues[ it->second ]->GetInt(); 
    }

    return isOK;
} 

bool 
MCSettings::GetSetting
( 
    const std::string& name, 
    double& value
) const
{
    bool isOK( false);

    std::map< std::string, int >::const_iterator it = 
        fNameIndexMap.find( name );
    if ( it != fNameIndexMap.end() )
    {
        isOK = true;
        value = fSettingValues[ it->second ]->GetDouble(); 
    }

    return isOK;
} 

bool 
MCSettings::GetSetting
( 
    const std::string& name, 
    std::string& value
) const
{
    bool isOK( false);

    std::map< std::string, int >::const_iterator it = 
        fNameIndexMap.find( name );
    if ( it != fNameIndexMap.end() )
    {
        isOK = true;
        value = fSettingValues[ it->second ]->GetString(); 
    }

    return isOK;
} 
 
bool 
MCSettings::GetSetting
( 
    const std::string& name, 
    MCSettings& value
) const
{
    bool isOK( false);

    std::map< std::string, int >::const_iterator it = 
        fNameIndexMap.find( name );
    if ( it != fNameIndexMap.end() )
    {       
        IMCSettingValue* pValue = fSettingValues[ it->second ];
        if ( pValue->GetValueType() == IMCSettingValue::kVT_SettingList )
        {
            MCSettingListValue* pSettingList = ( MCSettingListValue*)pValue;
            if ( pSettingList )
            {
                isOK = true; 
                value = pSettingList->GetMCSettings();           
            }            
        }         
    }

    return isOK;
}

} // end of namespace MCCommon.